#pragma once

namespace xtd {

// converting_iterator is an iterator that wraps around another iterator,
// and changes only its dereference operation by introducing additional convertion functor

template <class C, class I> 
class converting_iterator_t 
{
public:
	typedef C convertor_type;
	typedef typename C::result_type value_type;
	typedef I wraped_iterator_type;
public:
	converting_iterator_t() { }
	converting_iterator_t(C c, I i)
		: c_(c), i_(i) { }
	converting_iterator_t(const converting_iterator_t & rhs)
		: c_(rhs.c_), i_(rhs.i_) { }
	bool operator == (const converting_iterator_t & rhs) const
		{ return i_ == rhs.i_; }
	bool operator != (const converting_iterator_t & rhs) const
		{ return i_ != rhs.i_; }
	converting_iterator_t & operator ++() {
		++i_;
		return * this;
	}
	converting_iterator_t & operator --() {
		--i_;
		return * this;
	}
	value_type operator * () 
		{ return c_(* i_); }
private:
	C c_;
	I i_;
};

template <class C, class I> 
inline converting_iterator_t<C,I> converting_iterator(C c, I i)
	{ return converting_iterator_t<C,I>(c, i); }

} // xtd
